<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <script src="./vconsole.js"></script>
    <script src="./jessibuca-pro.js"></script>
    <style>
        .root {
            display: flex;
            place-content: center;
            margin-top: 3rem;
        }

        .container-shell {
            backdrop-filter: blur(5px);
            background: hsla(0, 0%, 50%, 0.5);
            padding: 30px 4px 10px 4px;
            /* border: 2px solid black; */
            width: auto;
            position: relative;
            border-radius: 5px;
            box-shadow: 0 10px 20px;
        }

        .container-shell:before {
            content: "jessibuca TF stream demo player";
            position: absolute;
            color: darkgray;
            top: 4px;
            left: 10px;
            text-shadow: 1px 1px black;
        }

        #container {
            background: rgba(13, 14, 27, 0.7);
            width: 900px;
            height: 568px;
        }

        .input {
            display: flex;
            margin-top: 10px;
            color: white;
            place-content: stretch;
        }

        .input2 {
            bottom: 0px;
        }

        .input input {
            flex: auto;
        }

        .err {
            position: absolute;
            top: 40px;
            left: 10px;
            color: red;
        }

        .option {
            position: absolute;
            top: 4px;
            right: 10px;
            display: flex;
            place-content: center;
            font-size: 12px;
        }

        .option span {
            color: white;
        }

        .page {
            background: url('./bg.jpg');
            background-repeat: no-repeat;
            background-position: top;
        }

        @media (max-width: 720px) {
            #container {
                width: 90vw;
                height: 52.7vw;
            }
        }
    </style>
</head>
<body class="page">
<div class="root">
    <div class="container-shell">
        <div id="container"></div>
        <div class="input">
            <div style="width: 900px">
                <span><span style="color: red">TPS:动态(根据流):</span>播放器的倍率播放完全是根据服务器端推流的速率，如果服务器端推的是一倍率且动态码率的流，
                播放器就按照一倍率动态码率渲染。<span style="color: green">例如 fps会15到30之间跳动。</span>
            </span>
            </div>
        </div>
        <div class="input">
            <div style="width: 900px">
                <span><span style="color: red">TPS:定频（本地设置）:</span>则支持播放器端控制播放速率(设置FPS+播放倍率)，播放器端设置的播放速率是固定的，不会随着流的速率变化而变化。
                支持设置播放器的播放倍率（提高渲染倍率）。<span
                        style="color: green">在推流码率足够的情况下，播放器会按照固定倍率播放</span>
            </span>
            </div>
        </div>
        <div class="input">
            <div style="width: 900px">
                <span><span style="color: red">TPS:解码前缓冲数据:</span>对于存在有些流会一下子以2倍甚至4倍的速率推送的情况，如果设置为true，则会根据计算出来的fps，只根据fps和倍率来解码数据，其他数据还是被缓存在队列中，等待解码。
            </span>
            </div>
        </div>
        <div class="input">
            <div style="width: 900px">
                <span><span style="color: red">TPS:服务器端倍率推流:</span> 如果服务器端按照倍率推流，播放器端也需要同步的以倍率播放【调用forward(rate)】接口
            </span>
            </div>
        </div>
        <div class="input">
            <div style="width: 900px">
                <span style="color: red">TPS:</span> 录像流暂只支持wasm（simd）解码,canvas渲染。
                <span>canvas渲染技术：</span>
                <select id="isUseWebGPU" onchange="replay()">
                    <option value="webgl">webgl</option>
                    <option value="webgpu" selected>webgpu</option>
                </select>
                <span id="supportWebgpu"></span>
            </div>
        </div>
        <div class="input">
            <div class="playbackForward">
                <span>FPS设置：</span>
                <select id="isUseFpsRender" style="width: 140px">
                    <option value="false" selected>动态(根据流)</option>
                    <option value="true">定频（本地设置）</option>
                </select>
                <span>是否解码前缓冲数据</span>
                <select id="isCacheBeforeDecodeForFpsRender" style="width: 50px">
                    <option value="true">是</option>
                    <option value="false" selected>否</option>
                </select>
                <span>是否显示操作按钮</span>
                <select id="isShowControl" style="width: 50px">
                    <option value="true" selected>是</option>
                    <option value="false">否</option>
                </select>
                <span>是否显示24H时间轴</span>
                <select id="isShow24H" style="width: 50px">
                    <option value="true" selected>是</option>
                    <option value="false">否</option>
                </select>

            </div>
        </div>
        <div class="input">
            <span>只解码I帧</span>
            <select id="onlyDecoderIFrame" style="width: 50px">
                <option value="1">1倍</option>
                <option value="2">2倍</option>
                <option value="4" selected>4倍</option>
                <option value="8">8倍</option>
            </select>

            <div class="playback-fps" style="margin-left: 10px">
                <span>FPS（定频(本地设置)生效）：</span><input style="width: 50px" type="text" id="playbackFps" value="25">帧
            </div>
            <div style="margin-left: 10px">
                <button onclick="replay()">重播</button>
            </div>
        </div>
        <div class="input">
            <div>输入URL：</div>
            <input
                autocomplete="on"
                id="playUrl"
                value=""
            />
            <button id="play">播放</button>
            <button id="pause">停止(流会断开)</button>
            <button id="playbackPause">停止(流不断开)</button>
        </div>
        <div class="input">
             <textarea name="" id="playbackTimes" style="width: 100%" rows="10">
                [{"start":1653840000,"end":1653841624},{"start":1653841634,"end":1653843420},{"start":1653843429,"end":1653843958},{"start":1653843967,"end":1653845688},{"start":1653845698,"end":1653846480},{"start":1653846490,"end":1653847199},{"start":1653847208,"end":1653848531},{"start":1653848541,"end":1653850863},{"start":1653850872,"end":1653853371},{"start":1653853381,"end":1653857885},{"start":1653857894,"end":1653858352},{"start":1653858362,"end":1653860545},{"start":1653860554,"end":1653861080},{"start":1653861090,"end":1653862017},{"start":1653862026,"end":1653863812},{"start":1653863822,"end":1653865325},{"start":1653865335,"end":1653867374},{"start":1653867383,"end":1653867698},{"start":1653867707,"end":1653868816},{"start":1653868826,"end":1653872829},{"start":1653872838,"end":1653877527},{"start":1653877537,"end":1653879799},{"start":1653879809,"end":1653881953},{"start":1653881963,"end":1653885397},{"start":1653885407,"end":1653886894},{"start":1653886904,"end":1653890591},{"start":1653890600,"end":1653894360},{"start":1653894370,"end":1653903276},{"start":1653903286,"end":1653912848},{"start":1653912858,"end":1653914424},{"start":1653914433,"end":1653915002},{"start":1653915011,"end":1653918125},{"start":1653918135,"end":1653921622},{"start":1653921631,"end":1653924609},{"start":1653924618,"end":1653926399}]
            </textarea>
        </div>
        <div class="input" style="line-height: 30px">
            <button id="destroy">销毁</button>
            <!--            <div id="playbackDom" style="width: 400px">-->
            <!--                <div class="playbackForward">-->
            <!--                    <span>播放倍率：</span>-->
            <!--                    <select id="playbackRate" style="width: 50px">-->
            <!--                        <option value="1" selected>1倍</option>-->
            <!--                        <option value="2">2倍</option>-->
            <!--                        <option value="4">4倍</option>-->
            <!--                        <option value="8">8倍</option>-->
            <!--                    </select>-->
            <!--                    <button id="playbackForward">快进</button>-->
            <!--                </div>-->

            <!--            </div>-->

        </div>
    </div>
</div>

<script>
    var $player = document.getElementById('play');
    var $pause = document.getElementById('pause');
    var $playbackPause = document.getElementById('playbackPause');
    var $playHref = document.getElementById('playUrl');
    var $container = document.getElementById('container');
    var $destroy = document.getElementById('destroy');
    var $playbackTime = document.getElementById('playbackTimes');
    var $playbackForward = document.getElementById('playbackForward');
    var $playbackFps = document.getElementById('playbackFps');
    var $isUseFpsRender = document.getElementById('isUseFpsRender');
    var $playbackDom = document.getElementById('playbackDom');
    var $isShowControl = document.getElementById('isShowControl'); // 是否显示按钮
    var $isShow24H = document.getElementById('isShow24H'); // 是否显示24H操作栏
    var $onlyDecoderIFrame = document.getElementById('onlyDecoderIFrame'); // 是否显示24H操作栏
    var $isCacheBeforeDecodeForFpsRender = document.getElementById('isCacheBeforeDecodeForFpsRender');
    var $supportWebgpu = document.getElementById('supportWebgpu');
    var $isUseWebGPU = document.getElementById('isUseWebGPU');

    var forceNoOffscreen = true; //
    var jessibuca = null;
    var isPlaybackPause = false;

    var isSupportWebgpu = 'gpu' in navigator;

    if (isSupportWebgpu) {
        $supportWebgpu.style.color = 'green';
        $supportWebgpu.innerHTML = '支持webGPU';
    } else {
        $supportWebgpu.style.color = 'red';
        $supportWebgpu.innerHTML = '暂不支持webGPU，降级到webgl渲染';
    }

    function isMobile() {
        return (/iphone|ipad|android.*mobile|windows.*phone|blackberry.*mobile/i.test(window.navigator.userAgent.toLowerCase()));
    }

    function isPad() {
        return (/ipad|android(?!.*mobile)|tablet|kindle|silk/i.test(window.navigator.userAgent.toLowerCase()));
    }

    const useVconsole = isMobile() || isPad()

    if (useVconsole && window.VConsole) {
        new window.VConsole();
    }

    function create() {
        const showOperateBtns = $isShowControl.value === 'true';
        const onlyDecoderIFrame = Number($onlyDecoderIFrame.value);
        jessibuca = new JessibucaPro({
            container: $container,
            videoBuffer: 0.2, // 缓存时长
            isResize: false,
            text: "",
            loadingText: "加载中",
            debug: true,
            debugLevel: 'debug',
            showBandwidth: showOperateBtns, // 显示网速
            showPlaybackOperate: showOperateBtns,
            operateBtns: {
                fullscreen: showOperateBtns,
                screenshot: showOperateBtns,
                play: showOperateBtns,
                audio: showOperateBtns,
                zoom: showOperateBtns,
                performance: showOperateBtns,
            },
            forceNoOffscreen: forceNoOffscreen,
            isNotMute: false,
            showPerformance: true,
            playbackForwardMaxRateDecodeIFrame: onlyDecoderIFrame,
            useWebGPU: $isUseWebGPU.value === 'webgpu' // 使用WebGPU
        },);

        jessibuca.onLog = msg => console.error(msg);
        jessibuca.onRecord = (status) => console.log('onRecord', status);
        jessibuca.onPause = () => console.log('onPause');
        jessibuca.onPlay = () => console.log('onPlay');
        jessibuca.onFullscreen = msg => console.log('onFullscreen', msg);
        jessibuca.onMute = msg => console.log('onMute', msg);
        $player.style.display = 'inline-block';
        $pause.style.display = 'none';
        $playbackPause.style.display = 'none';
        $destroy.style.display = 'none';
        // $playbackDom.style.display = 'none';


        jessibuca.on('playbackPreRateChange', (rate) => {
            jessibuca.forward(rate);
        })

    }


    create();

    function replay() {
        if (jessibuca) {
            jessibuca.destroy().then(() => {
                create();
                play();
            });
        } else {
            create();
            play();
        }
    }

    function play() {
        var href = $playHref.value;
        var playTimes = $playbackTime.value;
        var playFps = $playbackFps.value || 20;
        var isUseFpsRender = $isUseFpsRender.value;
        var playTimesArray = JSON.parse(playTimes);
        const isShow24H = $isShow24H.value === 'true';
        const isCacheBeforeDecodeForFpsRender = $isCacheBeforeDecodeForFpsRender.value === 'true';

        if (!href) {
            return
        }

        jessibuca.playback(href, {
            playList: playTimesArray,
            fps: playFps,
            showControl: isShow24H,
            isUseFpsRender: isUseFpsRender === 'true',
            isCacheBeforeDecodeForFpsRender: isCacheBeforeDecodeForFpsRender,
            showRateBtn: true,
            supportWheel: true,
            rateConfig: [
                {label: '正常', value: 1},
                {label: '2倍', value: 2},
                {label: '4倍', value: 4},
                {label: '8倍', value: 8},
            ]
        });
        isPlaybackPause = false;
        $player.style.display = 'none';
        $pause.style.display = 'inline-block';
        $playbackPause.style.display = 'inline-block';
        $destroy.style.display = 'inline-block';
    }


    $player.addEventListener('click', function () {
        var href = $playHref.value;
        var playTimes = $playbackTime.value;
        var playFps = $playbackFps.value || 20;
        var isUseFpsRender = $isUseFpsRender.value;
        var playTimesArray = JSON.parse(playTimes);
        const isShow24H = $isShow24H.value === 'true';
        const isCacheBeforeDecodeForFpsRender = $isCacheBeforeDecodeForFpsRender.value === 'true';

        if (!href) {
            return
        }

        if (isPlaybackPause) {
            jessibuca.playbackResume()
        } else {
            jessibuca.playback(href, {
                playList: playTimesArray,
                fps: playFps,
                showControl: isShow24H,
                isUseFpsRender: isUseFpsRender === 'true',
                isCacheBeforeDecodeForFpsRender: isCacheBeforeDecodeForFpsRender,
                showRateBtn: true,
                supportWheel: true,
                rateConfig: [
                    {label: '正常', value: 1},
                    {label: '2倍', value: 2},
                    {label: '4倍', value: 4},
                    {label: '8倍', value: 8},
                ]
            });
        }
        isPlaybackPause = false;
        $player.style.display = 'none';
        $pause.style.display = 'inline-block';
        $playbackPause.style.display = 'inline-block';
        $destroy.style.display = 'inline-block';
        // $playbackDom.style.display = 'block';
    }, false)


    $pause.addEventListener('click', function () {
        $player.style.display = 'inline-block';
        $pause.style.display = 'none';
        $playbackPause.style.display = 'none';
        jessibuca.pause();
    })

    $playbackPause.addEventListener('click', function () {
        $playbackPause.style.display = 'none';
        $pause.style.display = 'none';
        $player.style.display = 'inline-block';
        jessibuca.playbackPause();
        isPlaybackPause = true;
    })

    $destroy.addEventListener('click', function () {
        if (jessibuca) {
            jessibuca.destroy().then(() => {
                create();
            });
        } else {
            create();
        }

    })


    // $playbackForward.addEventListener('click', function () {
    //     const playbackRate = document.querySelector('#playbackRate').value;
    //
    //     if (jessibuca) {
    //         jessibuca.forward(playbackRate);
    //     }
    // })

</script>

</body>
</html>
